GtkUtils = GtkUtils or {};

-- 公用的功能函数
function GtkUtils.get_symbol_by_name(func_name, domain)
    -- 如果domain存在，则先从domain中查找
    if domain then
        -- 如果domain是字符串，则先从_G中查找到相应对象
        if type(domain[func_name]) == "string" then
            local domain_obj = _G[domain]
            -- 不为空，则查找此表中是否存在func_name
            if domain_obj then
                return domain_obj[func_name]
            end
        else
            return domain[func_name]
        end
    end
    return _G[func_name];
end

function GtkUtils.get_filesystem_sep()
    return "\\" --return package.config[0]
end

function GtkUtils.copy_to_left(t1, t2)
    -- 空表，直接返回，不操作
    if t2 == nil then
        return
    end
    for k, v in pairs(t2) do
        if (type(v) == "table") and (type(t1[k] or false) == "table") then
            if type(k) == "number" then
                local temp = {}
                GtkUtils.copy_to_left(temp, t2[k])
                table.insert(t1, temp)
            else
                GtkUtils.copy_to_left(t1[k], t2[k])
            end
        else
            if type(k) == "number" then
                table.insert(t1, v)
            else
                t1[k] = v
            end
        end
    end
end

function GtkUtils.check_file_exists(file_name)
    local file_handle = io.open(file_name, "r+")
	if file_handle ~= nil then
		io.close(file_handle) 
		return true
	else
		return false
	end
end

--分割到table中
function GtkUtils.string_split(str, reps)
    local resultStrList = {}
    string.gsub(str,'[^'..reps..']+',function (w)
        table.insert(resultStrList,w)
    end)
    return resultStrList
end

function GtkUtils.split_pathinfo(name)
    return {string.match(name, "(.-)(([^\\/]-)%.?([^%.\\/]*))$")};
end

function GtkUtils.split_pathinfo2(name)
    return {string.match(name, "(.-)(([^\\/]-)%.?([^%.\\/]*))")};
end

function GtkUtils.check_folder_exists(name)
    local function exists(name)
        if type(name)~="string" then
            return false
        end
        local ok, err, code = os.rename(name, name)
        if not ok then
           if code == 13 then
              -- Permission denied, but it exists
              return true
           end
        end
        return ok
    end
    
    if lfs ~= nil then
        if type(name)~="string" then return false end
        local cd = lfs.currentdir()
        local is = lfs.chdir(name) and true or false
        lfs.chdir(cd)
        return is
    end
    return (exists(name) and not GtkUtils.check_file_exists(name))
end

function GtkUtils.make_folder(name)
    if lfs ~= nil then
        if lfs.mkdir(name) then
            return true
        end
        return false
    end
    if os.execute("mkdir " .. name) then
        return true
    end
    return false
end

function GtkUtils.make_folders(name)
    -- 检查目录是否存在，已经存在，则返回true
    if GtkUtils.check_folder_exists(name) then
        return true
    end
    -- 去除末尾的/或者\，否则split_pathinfo会出错
    local short_name = name
    if GtkUtils.str_ends(name, "/") or GtkUtils.str_ends(name, "\\") then
        short_name = string.sub(name, 1, -2)
    end
    -- 否则，拆出父目录，并递归创建
    local parent_path = GtkUtils.split_pathinfo(short_name) [1]
    -- 父目录创建失败时，则返回false
    if not GtkUtils.make_folders(parent_path) then
        return false
    end
    -- 父目录创建成功时，则创建当前目录，并在创建成功时返回true
    if GtkUtils.make_folder(name) then
        return true
    end
    return false
end

function GtkUtils.table_copy_table(ori_tab)
    if (type(ori_tab) ~= "table") then
        return nil, 0
    end
    local new_tab = {}
	local max_index = 1
    for i,v in pairs(ori_tab) do
        local vtyp = type(v)
        if (vtyp == "table") then
            new_tab[i] = GtkUtils.table_copy_table(v)
        elseif (vtyp == "thread") then
            new_tab[i] = v
        elseif (vtyp == "userdata") then
            new_tab[i] = v
        else
            new_tab[i] = v
        end
		max_index = max_index + 1
    end
    return new_tab, max_index
end

function GtkUtils.get_current_file_path()
    return string.match(string.gsub(debug.getinfo(1,"S").source:sub(2), "\\", "/"), "^.*/")
end

function GtkUtils.str_starts(String,Start)
    return string.sub(String,1,string.len(Start))==Start
end
 
function GtkUtils.str_ends(String,End)
    return End=='' or string.sub(String,-string.len(End))==End
end

-- 检测表中是否有特定元素
function GtkUtils.contains(ele, tbl)
    for i = 1,#tbl do
        if tbl[i] == ele then
            return true;
        end
    end
    return false
end

-- 返回表1中去除表2中相同元素后的集合，表1中相同数值的元素也会被剔除
function GtkUtils.intersect(tbl1, tbl2)
    -- 表2中，如果没有内容，直接返回表1
    if #tbl2 == 0 then
        return tbl1
    end
    local tbl1_map = {}
    -- 创建一个map
    for _, v in ipairs(tbl1) do tbl1_map[v] = true end
    -- 开始过滤
    for _, v in ipairs(tbl2) do
        tbl1_map[v] = nil
    end
    -- 重新生成一个表
    local result = {}
    for k, _ in pairs(tbl1_map) do
        table.insert(result, k)
    end
    return result;
end

function GtkUtils.items_is_in_table(tbl1, tbl2)
    for _, item in pairs(tbl1) do
        if not tbl2[item] then
            return false
        end
    end
    return true
end

-- 如果表1中的任何一个元素在表2中，则返回true
function GtkUtils.one_item_of_table_is_in_table2(tbl1, tbl2)
    for _, item in ipairs(tbl1) do
        for _, item2 in ipairs(tbl2) do
            if item == item2 then
                return true
            end
        end
    end
    return false
end

-- 两个数组，第一个数组是第二个数组的子集
function GtkUtils.table_has_same_values(tbl1, tbl2)
    -- 遍历第一个数组的每一项
    for _, item in ipairs(tbl1) do
        local has_same = false
        -- 与第二个数组的每一项进行比较，
        for _, item2 in ipairs(tbl2) do
            if item == item2 then
                has_same = true
                break;
            end
        end
        if not has_same then
            return false
        end
    end
    return true
end

function GtkUtils.table_length(ori_tbl)
    if (type(ori_tbl) ~= "table") then
        return 0
    end
	local max_index = 0
	-- must use pairs function
    for _, _ in pairs(ori_tbl) do
		max_index = max_index + 1
    end
    return max_index
end

function GtkUtils.trim2(s)
	local l = 1
	while string.sub(s, l, l) == ' ' do
	  l = l+1
	end
	local r = string.len(s)
	while string.sub(s,r,r) == ' ' do
	  r = r - 1
	end
	while string.sub(s,r,r) == '\r' do
        r = r - 1
    end
	while string.sub(s,r,r) == '\n' do
        r = r - 1
    end
	return string.sub(s,l,r)
end

function GtkUtils.trim (str)
    if str == '' then
      return str
    else  
      local startPos = 1
      local endPos   = #str
  
      while (startPos < endPos and str:byte(startPos) <= 32) do
        startPos = startPos + 1
      end
  
      if startPos >= endPos then
        return ''
      else
        while (endPos > 0 and str:byte(endPos) <= 32) do
          endPos = endPos - 1
        end
  
        return str:sub(startPos, endPos)
      end
    end
end -- .function trim
